package mapi.flightrecorder;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.xmlpull.v1.XmlSerializer;

import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.database.Cursor;
import android.location.Location;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;
import android.preference.Preference.OnPreferenceClickListener;
import android.util.Log;
import android.util.Xml;
import android.widget.Toast;

public class Prefs_Export extends PreferenceActivity {

	final int colTime = 0;
	final int colLongitude = 1;
	final int colLatitude = 2;
	final int colAltitude = 3;
	final int colBearing = 4;
	final int colSpeed = 5;
	final int colAccuracy = 6;
	final int colAirport1 = 7;
	final int colAirport2 = 8;
	final int colAirport3 = 9;
	final int colAirport4 = 10;

	int sessionid;
	private String FilePath;
	private String Model;
	private boolean SendEmail;
	private String EmailAddress;

	private boolean FollowAnimatedModel;
	private String AnimatedModelCameraRange;
	private String AnimatedModelCameraTilt;

	private String AltitudeOffset;
	private String FpvCameraTilt;

	// private XmlSerializer serializer;
	DataBaseHelper databasehelper;

	private File FileOutput;
	private String AnimatedModelSpeed;
	private boolean CopyToExternalStorage;


	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		Bundle extras = getIntent().getExtras();
		sessionid = extras.getInt("sessionid");
		databasehelper = new DataBaseHelper(getApplicationContext());

		addPreferencesFromResource(R.layout.prefs_export);
		GetModels();
		Preference bExport = (Preference) findPreference("bExport");
		bExport.setOnPreferenceClickListener(new OnPreferenceClickListener() {

			public boolean onPreferenceClick(Preference preference) {
				Export();
				return true;
			}

		});

	}

	private void Export() {

		if (IsExternalStorageAvailable() == false) {
			Toast.makeText(
					getApplicationContext(),
					"Unable to write on external storage, please disconnect the phone from your computer",
					Toast.LENGTH_SHORT).show();
			return;
		}

		AsyncTaskHelper ExportTask = new AsyncTaskHelper();
		ExportTask.execute();

		if (SendEmail == true) {
			SendEmail();
		}

	}

	private void GetPreferences() {
		SharedPreferences settings = PreferenceManager
				.getDefaultSharedPreferences(this);

		FilePath = settings.getString("FilePath", "/sdcard/");
		Model = settings.getString("Model", "plane.dae");
		SendEmail = settings.getBoolean("SendEmail", true);
		EmailAddress = settings.getString("EmailAddress", "");

		FollowAnimatedModel = settings.getBoolean("FollowAnimatedModel", true);
		AnimatedModelCameraRange = settings.getString(
				"AnimatedModelCameraRange", "50");
		AnimatedModelCameraTilt = settings.getString("AnimatedModelCameraTilt",
				"70");

		AltitudeOffset = settings.getString("AltitudeOffset", "0");
		AnimatedModelSpeed = settings.getString("AnimatedModelSpeed", "1");
		CopyToExternalStorage = settings.getBoolean("CopyToExternalStorage",
				true);
		FpvCameraTilt = settings.getString("FpvCameraTilt", "90");

	}

	private void GetModels() {
		ListPreference lpModel = (ListPreference) findPreference("Model");
		if (lpModel != null) {
			CharSequence Models[] = null;

			try {
				Models = getAssets().list("models");
			} catch (IOException e) {

			}
			lpModel.setEntries(Models);
			lpModel.setEntryValues(Models);
		}
	}

	

	public void SendEmail() {
		String emailList[] = { EmailAddress };
		Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
		emailIntent.setType("text/html");
		emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, emailList);
		emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Export "
				+ getString(R.string.app_name) + " session ID " + sessionid);
		String emailbody = databasehelper.GetEmailBody(sessionid);
		emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, emailbody);
		Uri FileOutputUri = Uri.fromFile(FileOutput);
		emailIntent.putExtra(Intent.EXTRA_STREAM, FileOutputUri);
		startActivity(emailIntent);
	}

	private String getDecSecond(long millis) {

		int seconds = (int) ((millis / 1000) % 60);
		int milliseconds = (int) (millis % 1000);

		String aa = String.format("%02d.%03d", seconds, milliseconds);
		return aa;
	}



	private boolean IsExternalStorageAvailable() {

		boolean mExternalStorageWriteable = false;
		String state = Environment.getExternalStorageState();

		if (Environment.MEDIA_MOUNTED.equals(state)) {
			// We can read and write the media
			mExternalStorageWriteable = true;

		} else {
			// Something else is wrong. It may be one of many other states, but
			// all we need
			// to know is we can neither read nor write
			mExternalStorageWriteable = false;
		}
		return mExternalStorageWriteable;
	}

	private class AsyncTaskHelper extends AsyncTask<Void, Integer, Void> {

		private ProgressDialog mProgressDialog = new ProgressDialog(
				Prefs_Export.this);
		
		boolean IsFirstAnimatedUpdate = true;
		private FileOutputStream fosLineStringExtruded;
		private FileOutputStream fosLineString;
		private FileOutputStream fosFirstPersonView;
		private FileOutputStream fosAnimatedModel;
		private FileOutputStream fosInitKml;
		private XmlSerializer serLineStringExtruded;
		private XmlSerializer serLineString;
		private XmlSerializer serFirstPersonView;		
		private XmlSerializer serAnimatedModel;
		private XmlSerializer serInitKml;
		private File fileAnimatedModel;
		private File fileFirstPersonView;
		private File fileLineString;
		private File fileLineStringExtruded;
		private File fileInitKml;

		private File fileCloseKml;


		private boolean ClampToGround;
		private boolean WasClampToGround;

		ArrayList<String> arrAirports;

		
				
				

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
			mProgressDialog.setMessage("Please wait");
			mProgressDialog.setMax(databasehelper.GetUpdatesCount(sessionid));
			mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
			mProgressDialog.show();
		}

		@Override
		protected void onProgressUpdate(Integer... values) {
			mProgressDialog.setProgress(values[0]);
		}

		@Override
		protected Void doInBackground(Void... arg0) {

			GetPreferences();
			Cursor cursor = databasehelper.GetCursorSession(sessionid);
			cursor.moveToFirst();
			
			double Longitude = cursor.getDouble(colLongitude);
			double Latitude = cursor.getDouble(colLatitude);
			double Altitude = cursor.getDouble(colAltitude);
			float Speed = cursor.getFloat(colSpeed);
			float Accuracy = cursor.getFloat(colAccuracy);
			float Bearing = cursor.getFloat(colBearing);
			long Time = cursor.getLong(colTime);
			String IcaoAirport1 = cursor.getString(colAirport1);
			String IcaoAirport2 = cursor.getString(colAirport2);
			String IcaoAirport3 = cursor.getString(colAirport3);
			String IcaoAirport4 = cursor.getString(colAirport4);
			Location airport1 = databasehelper.GetAirportLocation(IcaoAirport1);
			Location airport2 = databasehelper.GetAirportLocation(IcaoAirport2);	
			Location airport3 = databasehelper.GetAirportLocation(IcaoAirport3);	
			Location airport4 = databasehelper.GetAirportLocation(IcaoAirport4);	
			Location fix = new Location("provider");
			InitFirstPersonView();
			InitLinestring();
			InitLinestringExtruded();
			InitKml();
			
			arrAirports = new ArrayList<String>();
			
			while (cursor.isAfterLast() == false) {
				publishProgress(cursor.getPosition());
				
				
								
				if (IcaoAirport1.equals(cursor.getString(colAirport1)) == false){
					IcaoAirport1 = cursor.getString(colAirport1);
					airport1 = databasehelper.GetAirportLocation(IcaoAirport1);	
				};
				
				if (IcaoAirport2.equals(cursor.getString(colAirport2)) == false){
					IcaoAirport2 = cursor.getString(colAirport2);
				
					airport2 = databasehelper.GetAirportLocation(IcaoAirport2);	
				};	
				
				if (IcaoAirport3.equals(cursor.getString(colAirport3)) == false){
					IcaoAirport3 = cursor.getString(colAirport3);
		
					airport3 = databasehelper.GetAirportLocation(IcaoAirport3);	
				};	
				
				if (IcaoAirport4.equals(cursor.getString(colAirport4)) == false){
					IcaoAirport4 = cursor.getString(colAirport4);
				
					airport4 = databasehelper.GetAirportLocation(IcaoAirport4);	
				};	
			
				
				Longitude = cursor.getDouble(colLongitude);
				Latitude = cursor.getDouble(colLatitude);
				Altitude = cursor.getDouble(colAltitude);
				Speed = cursor.getFloat(colSpeed);
				Accuracy = cursor.getFloat(colAccuracy);
				Bearing = cursor.getFloat(colBearing);
				Time = cursor.getLong(colTime);						
				
				fix.setLongitude(Longitude);
				fix.setLatitude(Latitude);
				fix.setAltitude(Altitude);
				fix.setSpeed(Speed);
				fix.setAccuracy(Accuracy);
				fix.setBearing(Bearing);
				fix.setTime(Time);
							
				float distanceAirport1 = airport1.distanceTo(fix);	
		
				if (distanceAirport1 < 2000 && fix.getAltitude() < airport1.getAltitude()) {
					ClampToGround = true;}
				else {
					ClampToGround = false;	
				}

				
				if (ClampToGround != WasClampToGround && cursor.isFirst() == false) { //if clamptoground has changed, create a new line
					NewLineString();				
					NewLineStringExtruded();	
				}

				AddLineStringExtruded(Longitude, Latitude, Altitude);
				AddLineString(Longitude, Latitude, Altitude);
				AddFirstPersonView(Longitude, Latitude, Altitude, Speed,
						Accuracy, Bearing, Time);
				AddAnimatedModel(Longitude, Latitude, Altitude, Speed,
						Accuracy, Bearing, Time);

				WasClampToGround = ClampToGround;
				cursor.moveToNext();
				}

			CloseLineStringExtruded();
			CloseLineString();
			CloseFirstPersonView();
			CloseAnimatedModel();
			CloseKml();
			
			cursor.close();
			FileOutput = zip();

			return null;
		}


		private void AddarrAirports(String icaoAirport) {
			
			for (int i=0; i<arrAirports.size(); i++) {
	            String st = arrAirports.get(i);
	            if (st.equals(icaoAirport)) {
	            	return;
	            }
	            	
	        }
			arrAirports.add(icaoAirport);
	     }

		private void NewLineString() {
			try {
				serLineString.endTag(null, "coordinates");
				serLineString.endTag(null, "LineString");
				serLineString.endTag(null, "Placemark");
				serLineString.startTag(null, "Placemark");
				serLineString.startTag(null, "name");
				serLineString.text("LineString");
				serLineString.endTag(null, "name");
				serLineString.startTag(null, "styleUrl");
				serLineString.text("#style1");
				serLineString.endTag(null, "styleUrl");
				serLineString.startTag(null, "LineString");
				serLineString.startTag(null, "altitudeMode");
				if (ClampToGround == true) {
					serLineString.text("clampToGround");
				} else {
					serLineString.text("absolute");
				}
				serLineString.endTag(null, "altitudeMode");
				serLineString.startTag(null, "coordinates");
				serLineString.flush();
			} catch (Exception e) {
	
			}
			

		}

		@Override
		protected void onPostExecute(Void result) {
			mProgressDialog.dismiss();
			setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
		}

		private void InitKml() {
			serInitKml = Xml.newSerializer();
			try {
				fileInitKml = new File(getFilesDir() + "/InitKml"); 
				fosInitKml = new FileOutputStream(fileInitKml);
				
				serInitKml.setOutput(fosInitKml, "UTF-8");
				serInitKml
						.setFeature(
								"http://xmlpull.org/v1/doc/features.html#indent-output",
								true);
				
				serInitKml.startDocument(null, null);
				
				serInitKml.startTag(null, "kml");
				serInitKml.attribute(null, "xmlns",
						"http://www.opengis.net/kml/2.2");
				serInitKml.attribute(null, "xmlns:gx",
						"http://www.google.com/kml/ext/2.2");

				serInitKml.startTag(null, "Document");
				serInitKml.flush();
			} catch (Exception e) {
			}
		}
		
		private void InitLinestringExtruded() {

			serLineStringExtruded = Xml.newSerializer();
			try {
				fileLineStringExtruded = new File(getFilesDir() + "/LineStringExtruded"); 
				fosLineStringExtruded = new FileOutputStream(fileLineStringExtruded);
						
				serLineStringExtruded.setOutput(fosLineStringExtruded, "UTF-8");
				serLineStringExtruded
						.setFeature(
								"http://xmlpull.org/v1/doc/features.html#indent-output",
								true);
				serLineStringExtruded.startTag(null, "Style");
				serLineStringExtruded.attribute(null, "id", "style1");
				serLineStringExtruded.startTag(null, "LineStyle");
				serLineStringExtruded.startTag(null, "color");
				serLineStringExtruded.text("641400C8");
				serLineStringExtruded.endTag(null, "color");
				serLineStringExtruded.startTag(null, "width");
				serLineStringExtruded.text("4");
				serLineStringExtruded.endTag(null, "width");
				serLineStringExtruded.endTag(null, "LineStyle");
		        serLineStringExtruded.startTag(null, "PolyStyle");
		        serLineStringExtruded.startTag(null, "color");
		        serLineStringExtruded.text("231400C8");
		        serLineStringExtruded.endTag(null, "color");
		        serLineStringExtruded.endTag(null, "PolyStyle");
				serLineStringExtruded.endTag(null, "Style");
				serLineStringExtruded.startTag(null, "Placemark");
				serLineStringExtruded.startTag(null, "name");
				serLineStringExtruded.text("LineString Extruded");
				serLineStringExtruded.endTag(null, "name");
				serLineStringExtruded.startTag(null, "styleUrl");
				serLineStringExtruded.text("#style1");
				serLineStringExtruded.endTag(null, "styleUrl");
				serLineStringExtruded.startTag(null, "LineString");
				serLineStringExtruded.startTag(null, "extrude");
				serLineStringExtruded.text("1");
				serLineStringExtruded.endTag(null, "extrude");
				serLineStringExtruded.startTag(null, "altitudeMode");
				if (ClampToGround == true) {
					serLineStringExtruded.text("clampToGround");
				} else {
					serLineStringExtruded.text("absolute");
				}
				serLineStringExtruded.endTag(null, "altitudeMode");
				serLineStringExtruded.startTag(null, "coordinates");

			} catch (Exception e) {
				Log.d("Exception", e.getMessage());
			}

		}

		private void AddLineStringExtruded(double longitude, double latitude,
				double altitude) {
			try {
				serLineStringExtruded.text(longitude + "," + latitude + ","
						+ altitude + "\n");
				serLineStringExtruded.flush();
			} catch (Exception e) {
			}
		}

		private void CloseLineStringExtruded() {

			try {
				serLineStringExtruded.endTag(null, "coordinates");
				serLineStringExtruded.endTag(null, "LineString");
				serLineStringExtruded.endTag(null, "Placemark");
				serLineStringExtruded.flush();
				fosLineStringExtruded.close();
				} catch (Exception e) {
			}

		}
		private void NewLineStringExtruded() {
			try {
			
				serLineStringExtruded.endTag(null, "coordinates");
				serLineStringExtruded.endTag(null, "LineString");
				serLineStringExtruded.endTag(null, "Placemark");
				serLineStringExtruded.startTag(null, "Placemark");
				serLineStringExtruded.startTag(null, "name");
				serLineStringExtruded.text("LineString Extruded");
				serLineStringExtruded.endTag(null, "name");
				serLineStringExtruded.startTag(null, "styleUrl");
				serLineStringExtruded.text("#style1");
				serLineStringExtruded.endTag(null, "styleUrl");
				serLineStringExtruded.startTag(null, "LineString");
				serLineStringExtruded.startTag(null, "extrude");
				serLineStringExtruded.text("1");
				serLineStringExtruded.endTag(null, "extrude");
				serLineStringExtruded.startTag(null, "altitudeMode");
				if (ClampToGround == true) {
					serLineStringExtruded.text("clampToGround");
				} else {
					serLineStringExtruded.text("absolute");
				}
				serLineStringExtruded.endTag(null, "altitudeMode");
				serLineStringExtruded.startTag(null, "coordinates");
				serLineStringExtruded.flush();

				
			} catch (Exception e) {
	
			}
			
		}
		private void InitLinestring() {
			serLineString = Xml.newSerializer();
			try {
				fileLineString = new File(getFilesDir() + "/LineString"); 
				fosLineString = new FileOutputStream(fileLineString);
				serLineString.setOutput(fosLineString, "UTF-8");
				serLineString
						.setFeature(
								"http://xmlpull.org/v1/doc/features.html#indent-output",
								true);
				serLineString.startTag(null, "Style");
				serLineString.attribute(null, "id", "style1");
				serLineString.startTag(null, "LineStyle");
				serLineString.startTag(null, "color");
				serLineString.text("641400FF");
				serLineString.endTag(null, "color");
				serLineString.startTag(null, "width");
				serLineString.text("4");
				serLineString.endTag(null, "width");
				serLineString.endTag(null, "LineStyle");
				serLineString.endTag(null, "Style");
				serLineString.startTag(null, "Placemark");
				serLineString.startTag(null, "name");
				serLineString.text("LineString");
				serLineString.endTag(null, "name");
				serLineString.startTag(null, "styleUrl");
				serLineString.text("#style1");
				serLineString.endTag(null, "styleUrl");
				serLineString.startTag(null, "LineString");
				serLineString.startTag(null, "altitudeMode");
				if (ClampToGround == true) {
					serLineString.text("clampToGround");
				} else {
					serLineString.text("absolute");
				}
				serLineString.endTag(null, "altitudeMode");
				serLineString.startTag(null, "coordinates");

			} catch (Exception e) {
			}
		}

		private void AddLineString(double longitude, double latitude,
				double altitude) {
			try {
				serLineString.text(longitude + "," + latitude + "," + altitude
						+ "\n");
				serLineString.flush();
			} catch (Exception e) {
			}
		}

		private void CloseLineString() {
			try {
				serLineString.endTag(null, "coordinates");
				serLineString.endTag(null, "LineString");
				serLineString.endTag(null, "Placemark");
				serLineString.flush();	
				fosLineString.close();
			} catch (Exception e) {
			}

		}

		private void InitFirstPersonView() {
			serFirstPersonView = Xml.newSerializer();
			try {
				fileFirstPersonView = new File(getFilesDir() + "/FirstPersonView"); 
				fosFirstPersonView = new FileOutputStream(fileFirstPersonView);
				serFirstPersonView.setOutput(fosFirstPersonView, "UTF-8");
				serFirstPersonView
						.setFeature(
								"http://xmlpull.org/v1/doc/features.html#indent-output",
								true);
				serFirstPersonView.startTag(null, "gx:Tour");
				serFirstPersonView.startTag(null, "name");
				serFirstPersonView.text("First person view");
				serFirstPersonView.endTag(null, "name");
				serFirstPersonView.startTag(null, "gx:Playlist");

			} catch (Exception e) {
			}
		}

		private void AddFirstPersonView(double longitude, double latitude,
				double altitude, float speed, float accuracy, float bearing,
				long time) {
			try {
				serFirstPersonView.startTag(null, "gx:FlyTo");
				serFirstPersonView.startTag(null, "gx:duration");
				serFirstPersonView.text("1");
				serFirstPersonView.endTag(null, "gx:duration");
				serFirstPersonView.startTag(null, "gx:flyToMode");
				serFirstPersonView.text("smooth");
				serFirstPersonView.endTag(null, "gx:flyToMode");
				serFirstPersonView.startTag(null, "Camera");
				serFirstPersonView.startTag(null, "longitude");
				serFirstPersonView.text(String.valueOf(longitude));
				serFirstPersonView.endTag(null, "longitude");
				serFirstPersonView.startTag(null, "latitude");
				serFirstPersonView.text(String.valueOf(latitude));
				serFirstPersonView.endTag(null, "latitude");
				serFirstPersonView.startTag(null, "altitude");
				if (ClampToGround == true) {
					serFirstPersonView.text("2");
				} else {
					double alti = altitude
							+ Double.parseDouble((AltitudeOffset));
					serFirstPersonView.text(String.valueOf(alti));
				}
				serFirstPersonView.endTag(null, "altitude");
				serFirstPersonView.startTag(null, "heading");
				serFirstPersonView.text(String.valueOf(bearing));
				serFirstPersonView.endTag(null, "heading");
				serFirstPersonView.startTag(null, "tilt");
				serFirstPersonView.text(String.valueOf(FpvCameraTilt));
				serFirstPersonView.endTag(null, "tilt");
				serFirstPersonView.startTag(null, "altitudeMode");
				if (ClampToGround == true) {
					serFirstPersonView.text("relativeToGround");
				} else {
					serFirstPersonView.text("absolute");
				}
				serFirstPersonView.endTag(null, "altitudeMode");
				serFirstPersonView.endTag(null, "Camera");
				serFirstPersonView.endTag(null, "gx:FlyTo");
				serFirstPersonView.flush();
			} catch (Exception e) {

			}// catch
		}

		private void CloseFirstPersonView() {

			try {
				serFirstPersonView.endTag(null, "gx:Playlist");
				serFirstPersonView.endTag(null, "gx:Tour");
				serFirstPersonView.flush();
				fosFirstPersonView.close();
			} catch (Exception e) {
			}

		}

		private void InitAnimatedModel(double longitude, double latitude, double altitude, float bearing) {
			serAnimatedModel = Xml.newSerializer();
			try {
				fileAnimatedModel = new File(getFilesDir() + "/AnimatedModel"); 
				fosAnimatedModel = new FileOutputStream(fileAnimatedModel);
				
				serAnimatedModel.setOutput(fosAnimatedModel, "UTF-8");
				serAnimatedModel
						.setFeature(
								"http://xmlpull.org/v1/doc/features.html#indent-output",
								true);
				
				serAnimatedModel.startTag(null, "Placemark");
				serAnimatedModel.startTag(null, "name");
				serAnimatedModel.text(Model);
				serAnimatedModel.endTag(null, "name");

				serAnimatedModel.startTag(null, "Model");
				serAnimatedModel.attribute(null, "id", Model);

				serAnimatedModel.startTag(null, "altitudeMode");
				serAnimatedModel.text("absolute");
				serAnimatedModel.endTag(null, "altitudeMode");

				serAnimatedModel.startTag(null, "Location");
				serAnimatedModel.attribute(null, "id", "loc");
				serAnimatedModel.startTag(null, "longitude");
				serAnimatedModel.text(String.valueOf(longitude));
				serAnimatedModel.endTag(null, "longitude");

				serAnimatedModel.startTag(null, "latitude");
				serAnimatedModel.text(String.valueOf(latitude));
				serAnimatedModel.endTag(null, "latitude");

				serAnimatedModel.startTag(null, "altitude");
				serAnimatedModel.text(String.valueOf(altitude));
				serAnimatedModel.endTag(null, "altitude");
				serAnimatedModel.endTag(null, "Location");

				serAnimatedModel.startTag(null, "Orientation");
				serAnimatedModel.attribute(null, "id", "ori");
				serAnimatedModel.startTag(null, "heading");
				serAnimatedModel.text(String.valueOf(bearing));
				serAnimatedModel.endTag(null, "heading");

				serAnimatedModel.startTag(null, "tilt");
				serAnimatedModel.text("0");
				serAnimatedModel.endTag(null, "tilt");

				serAnimatedModel.startTag(null, "roll");
				serAnimatedModel.text("0");
				serAnimatedModel.endTag(null, "roll");

				serAnimatedModel.endTag(null, "Orientation");

				serAnimatedModel.startTag(null, "Link");
				serAnimatedModel.startTag(null, "href");
				serAnimatedModel.text(Model);
				serAnimatedModel.endTag(null, "href");
				serAnimatedModel.endTag(null, "Link");
				serAnimatedModel.endTag(null, "Model");

				serAnimatedModel.endTag(null, "Placemark");
				
				serAnimatedModel.startTag(null, "gx:Tour");
				serAnimatedModel.startTag(null, "name");
				serAnimatedModel.text("Animated model");
				serAnimatedModel.endTag(null, "name");
				serAnimatedModel.startTag(null, "gx:Playlist");

				
			} catch (Exception e) {
			}
		}

		private void AddAnimatedModel(double longitude, double latitude,
				double altitude, float speed, float accuracy, float bearing,
				long time) {
			
			long timestamp_old = 0;
			long timestamp = 0;
			long longduration = 0;
			String stringduration = null;
			
			
			// si le curseur est a la premiere ligne
			if (IsFirstAnimatedUpdate) {
				stringduration = "1";
				IsFirstAnimatedUpdate = false;
			}
			// sinon on calcule duration
			else {
				// difference entre l'ancien timestamp et l'actuel
				timestamp_old = timestamp;
				timestamp = time;
				longduration = timestamp - timestamp_old;
				longduration = longduration	/ Integer.parseInt(AnimatedModelSpeed);
				stringduration = getDecSecond(longduration);

			}
			// on sauve le timestamp actuel pour la prochaine boucle
			timestamp = time;
			try{
			//
			// <gx:AnimatedUpdate>
			serAnimatedModel.startTag(null, "gx:AnimatedUpdate");

			// <gx:duration>6.5</gx:duration>
			serAnimatedModel.startTag(null, "gx:duration");
			serAnimatedModel.text(stringduration);
			serAnimatedModel.endTag(null, "gx:duration");
			// <Update>
			serAnimatedModel.startTag(null, "Update");

			// <targetHref></targetHref>
			serAnimatedModel.startTag(null, "targetHref");
			serAnimatedModel.endTag(null, "targetHref");

			// <Change>
			serAnimatedModel.startTag(null, "Change");

			// <Location targetId="planeLocation">
			serAnimatedModel.startTag(null, "Location");
			serAnimatedModel.attribute(null, "targetId", "loc");
			serAnimatedModel.startTag(null, "longitude");
			serAnimatedModel.text(String.valueOf(longitude));
			serAnimatedModel.endTag(null, "longitude");

			serAnimatedModel.startTag(null, "latitude");
			serAnimatedModel.text(String.valueOf(latitude));
			serAnimatedModel.endTag(null, "latitude");

			if (ClampToGround == false) {
				serAnimatedModel.startTag(null, "altitude");
				serAnimatedModel.text(String.valueOf(altitude));
				serAnimatedModel.endTag(null, "altitude");
			}

			// </Location>
			serAnimatedModel.endTag(null, "Location");

			serAnimatedModel.startTag(null, "Orientation");
			serAnimatedModel.attribute(null, "targetId", "ori");
			serAnimatedModel.startTag(null, "heading");
			serAnimatedModel.text(String.valueOf(bearing));
			serAnimatedModel.endTag(null, "heading");
			serAnimatedModel.endTag(null, "Orientation");

			// </Change>
			serAnimatedModel.endTag(null, "Change");
			// </Update>
			serAnimatedModel.endTag(null, "Update");
			// </gx:AnimatedUpdate>
			serAnimatedModel.endTag(null, "gx:AnimatedUpdate");

			if (FollowAnimatedModel == true) {
				serAnimatedModel.startTag(null, "gx:FlyTo");
				serAnimatedModel.startTag(null, "gx:duration");
				serAnimatedModel.text(stringduration);
				serAnimatedModel.endTag(null, "gx:duration");

				serAnimatedModel.startTag(null, "gx:flyToMode");
				serAnimatedModel.text("smooth");
				serAnimatedModel.endTag(null, "gx:flyToMode");
				serAnimatedModel.startTag(null, "LookAt");

				serAnimatedModel.startTag(null, "longitude");
				serAnimatedModel.text(String.valueOf(longitude));
				serAnimatedModel.endTag(null, "longitude");

				serAnimatedModel.startTag(null, "latitude");
				serAnimatedModel.text(String.valueOf(latitude));
				serAnimatedModel.endTag(null, "latitude");

				serAnimatedModel.startTag(null, "altitude");
				if (ClampToGround == true) {
					serAnimatedModel.text(String.valueOf(AltitudeOffset));
				} else {
					serAnimatedModel.text(String.valueOf(altitude));
				}
				serAnimatedModel.endTag(null, "altitude");
				serAnimatedModel.startTag(null, "range");
				serAnimatedModel.text(String
						.valueOf(AnimatedModelCameraRange));
				serAnimatedModel.endTag(null, "range");

				serAnimatedModel.startTag(null, "heading");
				serAnimatedModel.text(String.valueOf(bearing));
				serAnimatedModel.endTag(null, "heading");

				serAnimatedModel.startTag(null, "tilt");
				serAnimatedModel
						.text(String.valueOf(AnimatedModelCameraTilt));
				serAnimatedModel.endTag(null, "tilt");

				serAnimatedModel.startTag(null, "altitudeMode");
				if (ClampToGround == true) {
					serAnimatedModel.text("relativeToGround");
				} else {
					serAnimatedModel.text("absolute");

				}
				serAnimatedModel.endTag(null, "altitudeMode");

				serAnimatedModel.endTag(null, "LookAt");
				serAnimatedModel.endTag(null, "gx:FlyTo");
			}// end if followanimated = true

			serAnimatedModel.flush();
			} catch (Exception e) {
			}


		}

		private void CloseAnimatedModel() {
			try {
				serAnimatedModel.endTag(null, "gx:Playlist");
				serAnimatedModel.endTag(null, "gx:Tour");
				serAnimatedModel.flush();
				fosAnimatedModel.close();
				
			} catch (Exception e) {
			}
        
		}

		private void CloseKml(){
			
			try {
				fileCloseKml = new File(getFilesDir() + "/CloseKml");
		
				 FileWriter filewriter = new FileWriter(fileCloseKml);                  
			        BufferedWriter bufferedwriter = new BufferedWriter(filewriter); 
			        bufferedwriter.write("</Document>");
			        bufferedwriter.newLine();
			        bufferedwriter.write("</kml>");
			        bufferedwriter.close();
				} 
			catch (Exception e) {
			}	
			
		}
		
		public File zip() {
			
			String Filename = databasehelper.GetFilename(sessionid);

			// Create a buffer for reading the files
			byte[] buffer = new byte[1024];

			File OutputZip = new File(getExternalFilesDir(null),
					Filename + ".kmz");
			try {

				FileOutputStream fos = new FileOutputStream(OutputZip);
				ZipOutputStream zipoutputstream = new ZipOutputStream(fos);
				zipoutputstream.putNextEntry(new ZipEntry(Filename + ".kml"));
				int len;
				FileInputStream fileinputstream;
				
				
				fileinputstream = new FileInputStream(fileInitKml);				
				while ((len = fileinputstream.read(buffer)) > 0) {
					zipoutputstream.write(buffer, 0, len);
				}
								
				fileinputstream = new FileInputStream(fileAnimatedModel);				
				while ((len = fileinputstream.read(buffer)) > 0) {
					zipoutputstream.write(buffer, 0, len);
				}
				
				fileinputstream = new FileInputStream(fileFirstPersonView);
				while ((len = fileinputstream.read(buffer)) > 0) {
					zipoutputstream.write(buffer, 0, len);
				}
				
				fileinputstream = new FileInputStream(fileLineString);				
				while ((len = fileinputstream.read(buffer)) > 0) {
					zipoutputstream.write(buffer, 0, len);
				}
				
				fileinputstream = new FileInputStream(fileLineStringExtruded);				
				while ((len = fileinputstream.read(buffer)) > 0) {
					zipoutputstream.write(buffer, 0, len);
				}
				
				fileinputstream = new FileInputStream(fileCloseKml);				
				while ((len = fileinputstream.read(buffer)) > 0) {
					zipoutputstream.write(buffer, 0, len);
				}			
								
				zipoutputstream.closeEntry();
				fileinputstream.close();			

				// model
				
				InputStream inputstream = getAssets().open("models/" + Model);
				zipoutputstream.putNextEntry(new ZipEntry(Model));
				while ((len = inputstream.read(buffer)) > 0) {
					zipoutputstream.write(buffer, 0, len);
				}
				zipoutputstream.closeEntry();
				inputstream.close();

				// Complete the ZIP file
				zipoutputstream.close();

			} catch (Exception e) {
				Log.d("Exception", e.getMessage());
			}

			return OutputZip;
		}
	}
}
